package com.lightsaber.trade.cloth.dao.category;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.lang.StringUtils;
import org.hibernate.Query;
import org.hibernate.criterion.Order;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import org.springside.modules.orm.Page;

import com.lightsaber.trade.core.dao.BaseDao;
import com.lightsaber.trade.cloth.entity.category.Category;

@Component
public class CategoryDao extends BaseDao<Category, String> {
    private final static Logger log = LoggerFactory.getLogger(CategoryDao.class);

    // find by category
    public List<Category> findByCategory(final Category category) {
        like("planningExerciseName", category.getPlanningExerciseName());
        eq("planYear", category.getPlanYear());

        return list();
    }

    public long findByOwnerNodeAndBranchName(final Category category) {
        eq("ownerNode.id", category.getOwnerNode().getId());
        eq("branchName", category.getBranchName());
        ne("id", category.getId());
        return count();
    }

    public long findByOwnerNodeAndBranchName(final String ownerId, final String newBranchName) {
        eq("ownerNode.id", ownerId);
        eq("branchName", newBranchName);
        return count();
    }

    public List<Category> findByExerciseYearForMasterTree(final Category category) {
        eq("planYear", category.getPlanYear());
        isNull("ownerNode");
        return list();
    }

    public long findByExerciseNameForMasterTree(final String planningExerciseName) {
        eq("planningExerciseName", planningExerciseName);
        isNull("ownerNode");
        return count();
    }

    public long findByExerciseNameForMasterTree(final Category category) {
        eq("planningExerciseName", category.getPlanningExerciseName());
        ne("id", category.getId());
        isNull("ownerNode");
        return count();
    }

    public Category findMasterTreeByPlanYear(final Integer planYear) throws Exception {
        eq("planYear", planYear);
        isNull("ownerNode");

        try {
            return unique();
        } catch (Exception e) {
            log.error("PlanYear {} has multiple master tree", planYear);
            throw e;
        }
    }

    public Page<Category> findPage(final Category category, final Page<Category> page,
            final String[] roles, final boolean isAdmin) {

        if (roles.length == 0) {
            return page;
        }

        Map<String, Object> map = new HashMap<String, Object>();

        String hql = "";
        if (isAdmin) {
            hql = "select distinct ca from Category ca where ((ca.id in (select node.category.id from CategoryNode node)"
                    + " and ca.ownerNode.id is null )"
                    + " or ca.ownerNode.id in(select owner.categoryNode.id from CategoryOwner owner where owner.roleCode in (:roles)))";
        } else {
            // hql =
            // "select distinct ca from Category ca join ca.ownerNode as ownern "
            // +
            // "join ownern.categoryOwners as cateowner where cateowner.roleCode in (:roles) ";

            hql = "select distinct ca from Category ca "
                    + "where ca.ownerNode.id in(select owner.categoryNode.id from CategoryOwner owner  where owner.roleCode in (:roles)) ";
        }
        map.put("roles", roles);
        if (category != null) {
            if (category.getPlanYear() != null && category.getPlanYear() != 0) {
                hql += " and ca.planYear=:planYear ";
                map.put("planYear", category.getPlanYear());
            }
            if (StringUtils.isNotBlank(category.getBranchName())) {
                // hql +=
                // " and ca.branchName like '%"+category.getBranchName()+"%' ";
                hql += " and ca.branchName like :branchName ";
                map.put("branchName", "%" + category.getBranchName() + "%");
            }
            if (StringUtils.isNotBlank(category.getPlanningExerciseName())) {
                // hql +=
                // " and ca.planningExerciseName like '%"+category.getPlanningExerciseName()+"%' ";
                hql += " and ca.planningExerciseName like :planningExerciseName";
                map.put("planningExerciseName", "%" + category.getPlanningExerciseName() + "%");
            }
        }
        hql += "  order by ca.planYear, ca.planningExerciseName, ca.branchName ";
        log.info("hql {}", hql);
        return findPage(page, hql, map);
    }

    public List<Category> findMasterTrees() {
        isNull("ownerNode");
        addOrder(Order.asc("planYear"));

        return list();
    }

    public List<Category> findBranchTreesByYear(final Integer planYear) {
        eq("planYear", planYear);
        isNotNull("ownerNode");
        return list();
    }

    @SuppressWarnings("unchecked")
    public List<Category> findBranchTreesByYearAndRole(final Integer exerciseYear, final String role) {

        String hql = "select distinct ca from Category ca join ca.ownerNode as ownern "
                + "join ownern.categoryOwners as cateowner with cateowner.roleCode =:role "
                + "where ca.planYear= :planYear";

        // 1.如果用户有权限,则继续查询 Branch Category
        Map<String, Object> values = new HashMap<String, Object>();
        values.put("role", role);
        values.put("planYear", exerciseYear);

        // Add the last parameter and execute hql
        Query q = this.createQuery(hql, values);

        return q.list();
    }

    @SuppressWarnings("unchecked")
    public List<Integer> getAllCategoryOrderByYear() {

        String hql = "select distinct ca.planYear from Category ca where ca.ownerNode is null order by ca.planYear";

        Query q = this.createQuery(hql, new HashMap<String, Object>());

        return q.list();
    }

    public void deleteCategoryByOwnerNodeId(final String ownerNodeId) {
        String hql = "delete from Category ca where ca.ownerNode.id= :ownerNodeId";
        Map<String, Object> values = new HashMap<String, Object>();
        values.put("ownerNodeId", ownerNodeId);
        Query q = this.createQuery(hql, values);
        q.executeUpdate();
    }

    public void deleteCategory(final String id) {
        String hql = "delete from Category ca where ca.id= :id";
        Map<String, Object> values = new HashMap<String, Object>();
        values.put("id", id);
        Query q = this.createQuery(hql, values);
        q.executeUpdate();
    }

    public List<Category> findByRole(final String role) {

        String hql = "select distinct ca from Category ca join ca.ownerNode as ownern "
                + "join ownern.categoryOwners as cateowner with cateowner.roleCode =:role ";

        // 1.如果用户有权限,则继续查询 Branch Category
        Map<String, Object> values = new HashMap<String, Object>();
        values.put("role", role);

        // Add the last parameter and execute hql
        Query q = this.createQuery(hql, values);

        return q.list();
    }

}
